/*
* 认证模块
* */

//引入config模块
const {token}=require('../config');
//引入sha1加密
const sha1 =require('sha1');
//引入 template 模块
const template = require('./template')
//引入 reply 模块
const reply = require('./reply')
//引入tooL模块
const {getUserDataAsync,parseXMLAsync,formatMessage} = require('../utils/tooL')
module.exports = () => {
    return async (req, res, next) => {
        /*
        signature: 微信的加密签名，结合你的token，timestamp和nonce经过某种算法生成的
        echostr: 随机字符串，微信后台随机生成的
        timestamp: 时间戳，对应当前时间
        nonce: 随机数，微信后台随机生成的

        01.服务器. 确认消息发送自微信后台
         - 结合你的token，timestamp和 nonce 根据某种算法计算得出的字符串是否与 signature 相等。
           - 相等：下一步
           - 不相等：返回错误信息
         - 具体怎么做的？某种算法是什么呢？
        });
        - 第一步：将三个字符串按字典序排序
                  - 123...abcdefg....   对应方法 arr.sort()
                - 第二步：将三个排序后的字符串拼接在一起，用sha1算法加密
                - 第三步：将加密后的字符串与 signature 进行对比，相等下一步，不等报错
           2. 返回echostr给微信后台，微信后台才会确认开发者的合法身份
              - 将 echostr 返回给微信后台
          */
        //获取参与加密的参数
        const {signature, echostr, timestamp, nonce} = req.query
        // - 将timestamp、nonce、token三个参数按照字典序排序并进行sha1加密
        const sha = sha1([token, timestamp, nonce].sort().join(''))
        /*
      微信服务器会主动发送两种方法的消息
        GET请求， 验证服务器有效性
        POST请求，微信服务器会将用户发送过来的消息转发到开发者服务器上
     */
        if (req.method === 'GET') {
            // - 将加密后生成字符串和微信签名进行对比，
            if (sha === signature) {
                //说明成功，返回echostr给微信服务器
                res.send(echostr)
            } else {
                //说明失败
                res.send('wrong')
            }
        } else if (req.method === 'POST') {
            //接受用户发送过来消息
            // console.log(req.query);
            /*
              { signature: 'c67250097842aa50990259fa3df052eeffcb1cee',
                timestamp: '1530000513',
                nonce: '53405765',
                openid: 'oAsoR1iP-_D3LZIwNCnK8BFotmJc' }  //用户的id
             */
            //验证消息是否来自于微信服务器
            if (sha !== signature) {
                //说明消息不是来自于微信服务器
                //过滤掉非法请求
                res.send('error');
                return
            }
            //接受请求体中的数据，流式数据  （接受到用户发送过来的消息）
            const xmlData=await getUserDataAsync(req);
            /*<xml><ToUserName><![CDATA[gh_6e655cb7aff4]]></ToUserName>  //开发者的id
                <FromUserName><![CDATA[olPN65wyVk3wA8NW1fhGI90AplsM]]></FromUserName>  //用户openid
                <CreateTime>1627121227</CreateTime>  //发送消息时间戳
                <MsgType><![CDATA[text]]></MsgType>  //发送消息类型
                <Content><![CDATA[1]]></Content>     //发送内容
                <MsgId>23294775132146258</MsgId>     //消息id 微信服务器会默认保存3天用户消息，通过id可以找到消息，三天后销毁
            </xml>*/
            //将xml数据转换js对象格式(但数据是xml对象的格式所以还需要过了一遍)
            const jsData = await parseXMLAsync(xmlData);
            // console.log(jsData)
            /*{
                xml: {
                  ToUserName: [ 'gh_6e655cb7aff4' ],
                  FromUserName: [ 'olPN65wyVk3wA8NW1fhGI90AplsM' ],
                  CreateTime: [ '1627122620' ],
                  MsgType: [ 'text' ],
                  Content: [ '9008' ],
                  MsgId: [ '23294795179709661' ]
                }
            }
            */
            //格式化数据
            const message = await formatMessage(jsData)
            /*{
              ToUserName: 'gh_6e655cb7aff4',
              FromUserName: 'olPN65wyVk3wA8NW1fhGI90AplsM',
              CreateTime: '1627123743',
              MsgType: 'text',
              Content: '叫哥哥',
              MsgId: '23294808875346466'
            }
            */
            //简单的自动回复，文本回复
            /*一旦遇到以下情况，微信都会在公众号会话中，向用户下发系统提示“该公众号暂时无法提供服务，请稍后再试”：
            *1、开发者在5秒内未回复任何内容
            * 2、开发者回复了异常数据，比如JSON数据.字符串.xml数据.中有多余的空格。。。等
            * */
            const options =reply(message)
            //最终回复用户信息
            const reqlyMessage=template(options);
            console.log(reqlyMessage)

            //返回响应给微信服务器
            res.send(reqlyMessage);
        }


    //如果开发者服务器没有响应给微信服务器，微信服务器会发送三次请求过来
    //     res.end('')
    }
}